home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Games / NeXTmj / Source / GameCoordinator.cc < prev    next >
Text File  |  1991-03-23  |  7KB  |  350 lines

  1.  
  2. /*
  3.  *
  4.  $Author$
  5.  $Header$
  6.  *
  7.  $Log$
  8.  */
  9.  
  10. #import    "GameCoordinator.h"
  11. #import    "Tile.h"
  12. #import    "TileIterator.h"
  13.  
  14. extern "C" {
  15. #import    <assert.h>
  16. #import    <string.h>
  17. }
  18.  
  19.  
  20. GameCoordinator::GameCoordinator( GameBoardView* view, TileCountManager* manager ) {
  21.  
  22.     int        board_num = -1;
  23.     
  24.     
  25.     initialized = NO;
  26.     
  27.     assert( view );
  28.     my_view = view;
  29.     assert( manager );
  30.     tile_count_manager = manager;
  31.     
  32.                                                 // Scan the command line and look
  33.                                                 //    for an optional board number.  The
  34.                                                 //    board number is a seed to the random
  35.                                                 //    number generator.
  36.     for( int i = 0; i < NXArgc; ++i )
  37.         if( !strncmp( NXArgv[ i ], "-b", strlen( "-b" )))
  38.             if(( i + 1 ) < NXArgc ) {
  39.                 board_num = atoi( NXArgv[ i + 1 ] );
  40.                 board_num %= 20011;
  41.             }
  42.  
  43.                                                 // Scramble the tiles on the game
  44.                                                 //    board.
  45.     if( board_num == -1 )
  46.         scrambler.scramble( tile_array );
  47.     else
  48.         scrambler.scramble( board_num, tile_array );
  49.     
  50.                                                 // Prepare the tiles for
  51.                                                 //    a the game.
  52.     prepareTilesForPlay();
  53.  
  54.                                                 // All tiles are unselected in their
  55.                                                 //    constructor but this method does
  56.                                                 //    some additional work.
  57.     unselectTiles();
  58.  
  59.                                                 // All tiles are placed on the board.
  60.     tile_count_manager->resetCount();
  61.     
  62.                                                 // Insure the view is dirty so that
  63.                                                 //    it'll be displayed when the window 
  64.                                                 //    is exposed.
  65.     updateView();
  66.  
  67.     initialized = YES;
  68. }
  69.  
  70.  
  71. void GameCoordinator::updateView( void ) {
  72.  
  73.  
  74.     [ my_view setNeedsDisplay:YES ];
  75.     if( initialized )
  76.         [ my_view display ];
  77. }
  78.  
  79.  
  80. void GameCoordinator::drawImage( void ) {
  81.  
  82.  
  83.     assert([ my_view isFocusView ]);
  84.                                             // Have each tile that is marked as 
  85.                                             //    not removed to draw itself on the
  86.                                             //    Game Board.
  87.     for( int i = 0; i < tile_array.size(); ++i )
  88.         if( !tile_array[ i ].isRemoved())
  89.             tile_array[ i ].drawImage( description_array[ i ]->tileLocation());
  90. }
  91.  
  92.  
  93. void GameCoordinator::helpClick( void ) {
  94.  
  95.  
  96.     unselectTiles();
  97.     help.helpClick( tile_array );
  98.     updateView();
  99. }
  100.  
  101.  
  102. void GameCoordinator::undoClick( void ) {
  103.  
  104.  
  105.     assert(( undoList.count() % 2 ) == 0 );
  106.  
  107.     help.resetHelp();
  108.  
  109.                                                 // If there are two tiles on the undo 
  110.                                                 //    list then mark them as not removed, 
  111.                                                 //    redraw the board, and mark all 
  112.                                                 //    tiles as not selected.
  113.     if( undoList.count()) {
  114.     
  115.         for( int i = 0; i < 2; ++i ) {
  116.             int    tile = undoList.lastValue();
  117.         
  118.             tile_array[ tile ].setRemoved( NO );
  119.              
  120.             undoList -= tile;
  121.         }
  122.         
  123.         updateSelectablilty();
  124.  
  125.         tile_count_manager->addTwo();
  126.     } else
  127.         NXBeep();
  128.  
  129.     unselectTiles();
  130.     updateView();
  131. }
  132.  
  133.  
  134. void GameCoordinator::unselectTiles( void ) {
  135.  
  136.  
  137.     for( int i = 0; i < tile_array.size(); ++i )
  138.         tile_array[ i ].setSelected( NO );
  139.     
  140.     first_selected_tile        =
  141.     second_selected_tile    = -1;
  142.  
  143.     updateView();
  144. }
  145.  
  146.  
  147. void GameCoordinator::againClick( void ) {
  148.  
  149.  
  150.                                                 // Again means to play the same tile
  151.                                                 //    scramble again.
  152.     help.resetHelp();
  153.     prepareTilesForPlay();
  154.     undoList.empty();
  155.     unselectTiles();
  156.     updateView();
  157.     
  158.     tile_count_manager->resetCount();
  159. }
  160.  
  161.  
  162.  
  163. void GameCoordinator::newClick( void ) {
  164.  
  165.     
  166.                                                 // Scramble the tiles and start
  167.                                                 //    a new game.
  168.     scrambler.scramble( tile_array );
  169.     undoList.empty();
  170.     help.resetHelp();
  171.     unselectTiles();
  172.     prepareTilesForPlay();
  173.     updateView();
  174.  
  175.     tile_count_manager->resetCount();
  176. }
  177.  
  178. void GameCoordinator::prepareTilesForPlay( void ) {
  179.  
  180.     int    i;
  181.     
  182.     
  183.                                                 // Set all tiles to a default
  184.                                                 //    state.
  185.     for( i = 0; i < tile_array.size(); ++i ) {
  186.         tile_array[ i ].setRemoved( NO );
  187.         tile_array[ i ].setSelected( NO );
  188.         tile_array[ i ].setSelectable( NO );
  189.     }
  190.     
  191.     updateSelectablilty();
  192. }
  193.  
  194.  
  195. void GameCoordinator::updateSelectablilty( void ) {
  196.  
  197.  
  198.                                                 // Any tile that is free on either its
  199.                                                 //    left or right and isn't covered
  200.                                                 //    is selectable
  201.     for( int i = 0; i < tile_array.size(); ++i ) {
  202.         BOOL    selectable = NO;
  203.         
  204.         if( !tile_array[ i ].isRemoved())
  205.             if( !isCovered( i ))
  206.                 if( isRightFree( i ) || isLeftFree( i )) 
  207.                     selectable = YES;
  208.         
  209.         tile_array[ i ].setSelectable( selectable );
  210.     }
  211. }
  212.  
  213.  
  214. BOOL GameCoordinator::isFree( IntegerList& list ) {
  215.  
  216.     BOOL    is_free = YES;
  217.     int        i;
  218.     
  219.     
  220.     list.beginIterate();
  221.     while(( i = list()) != -1 ) 
  222.         if( !tile_array[ i ].isRemoved())
  223.             is_free = NO;
  224.     
  225.     return is_free;
  226. }
  227.  
  228.  
  229. void GameCoordinator::click( const NXPoint* aPoint ) {
  230.  
  231.     int    theTile = tileForClick( aPoint );
  232.     
  233.     
  234.                                                 // Any click on the Game Board resets
  235.                                                 //    Help.
  236.     if( help.isSelected())
  237.         unselectTiles();
  238.     help.resetHelp();
  239.  
  240.     if( theTile != -1 ) {
  241.         if( tile_array[ theTile ].isSelectable()) {
  242.         
  243.                                                 // If the tile is being unselected
  244.                                                 //    the unselect it. 
  245.             if( theTile == first_selected_tile ) {
  246.                 tile_array[ first_selected_tile ].setSelected( NO );
  247.                 first_selected_tile = -1;
  248.             } else 
  249.                 if( theTile == second_selected_tile ) {
  250.                     tile_array[ second_selected_tile ].setSelected( NO );
  251.                     second_selected_tile = -1;
  252.                 } else
  253.                                                 // If tile isn't selected then
  254.                                                 //    this tile is selected.
  255.                     if( first_selected_tile == -1 ) {
  256.                         tile_array[ theTile ].setSelected( YES );
  257.                         first_selected_tile = theTile;
  258.                     } else
  259.                         if( second_selected_tile == -1 ) {
  260.                             tile_array[ theTile ].setSelected( YES );
  261.                             second_selected_tile = theTile;
  262.                         }
  263.             
  264.                                                 // If there are two tiles selected
  265.                                                 //    then compare their types.  If they're
  266.                                                 //    different then unselect the tiles.
  267.             if(( first_selected_tile != -1 ) && ( second_selected_tile != -1 ))
  268.                 if( tile_array[ first_selected_tile ].tileType() != tile_array[ second_selected_tile ].tileType()) {
  269.                     unselectTiles();
  270.                     NXBeep();
  271.                 }
  272.                 
  273.             updateView();
  274.         } else
  275.             NXBeep();
  276.     } else
  277.         NXBeep();
  278. }
  279.  
  280.  
  281. void GameCoordinator::doubleClick( const NXPoint* aPoint ) {
  282.  
  283.     int    theTile = tileForClick( aPoint );
  284.  
  285.  
  286.     if( theTile != -1 ) {
  287.         if( tile_array[ theTile ].isSelectable()) {
  288.         
  289.                                                 // if there isn't two tiles selected then
  290.                                                 //    try to select the tile double clicked.
  291.             if(( first_selected_tile == -1 ) || ( second_selected_tile == -1 ))
  292.                 click( aPoint );
  293.                                                 // There must be two tiles
  294.                                                 //    selected.
  295.             if(( first_selected_tile != -1 ) && ( second_selected_tile != -1 )) {
  296.             
  297.                                                 // Remove the tiles from the
  298.                                                 //    board and update the selectability
  299.                                                 //    of the surrounding tiles.
  300.                 assert( tile_array[ first_selected_tile ].tileType() == tile_array[ second_selected_tile ].tileType());
  301.                 removeTile( first_selected_tile );
  302.                 removeTile( second_selected_tile );
  303.                 tile_count_manager->subtractTwo();
  304.                 
  305.                 unselectTiles();
  306.             } else
  307.                 NXBeep();
  308.         } else
  309.             NXBeep();
  310.     } else
  311.         NXBeep();
  312. }
  313.  
  314.  
  315. int GameCoordinator::tileForClick( const NXPoint* aPoint ) {
  316.  
  317.     TileIterator    index = ( NUMBER_OF_TILES - 1 );
  318.     int                theTile = -1;
  319.     
  320.     
  321.     do { 
  322.         if( !tile_array[ index.value() ].isRemoved()) {
  323.             NXRect    r = {    0, 0,
  324.                             TILE_SIZE - TILE_SHIFT, TILE_SIZE - TILE_SHIFT };
  325.         
  326.             r.origin = description_array[ index.value() ]->tileLocation();
  327.             if( NXPointInRect( aPoint, &r )) 
  328.                 theTile = index.value();
  329.         }
  330.     } while(( theTile == -1 ) && ( --index >= 0 ));
  331.  
  332.     return theTile;
  333. }
  334.  
  335.  
  336. void GameCoordinator::removeTile( int tile ) {
  337.  
  338.     
  339.     undoList += tile;
  340.     
  341.     tile_array[ tile ].setRemoved( YES );
  342.     tile_array[ tile ].setSelected( NO );
  343.     tile_array[ tile ].setSelectable( NO );
  344.     
  345.     updateSelectablilty();
  346. }
  347.  
  348.  
  349.  
  350.